---
title: Design Considerations
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<a id="transaction-considerations"></a>

Designs that incorporate more complex features introduce further
considerations.
This section discusses how transactions interact with other 
<%=vars.product_name%> features.

-  **[Colocate Partitioned Regions](#colocate-PRs)**
-  **[Region Operations Return References](#copy-on-read-transactions)**
-  **[First Operation with Mixed Region Types](#first-op-with-mixed-types)**
-  **[Allowing Transactions to Work on Persistent Regions](#transactions-persistence)**
-  **[Mixing Transactions with Queries and Indexes](#transactions-queries)**
-  **[Mixing Transactions with Eviction](#transactions-eviction)**
-  **[Mixing Transactions with Expiration](#transactions-expiration)**
-  **[Changing the Handling of Dirty Reads](#transactions-dirty-reads)**

## <a id="colocate-PRs" class="no-quick-link"></a>Colocate Partitioned Regions

For performance,
transactions that operate on more than one partitioned region
require that those partitioned regions colocate their entries.
[Colocate Data from Different Partitioned Regions](../partitioned_regions/colocating_partitioned_region_data.html) describes how to colocate 
entries.

## <a id="copy-on-read-transactions" class="no-quick-link"></a>Region Operations Return References

For performance,
server-invoked region operations return references to region entries.
Any assignment to that reference changes the entry within the region.
This subverts the system's ability to maintain consistency
and the callback chain for handlers such as cache writers
and cache loaders.

Changing an entry using a reference from within a transaction executing
on a server has the same consistency issues, but is even worse,
as the change will not be seen as part of the transactional state.

There are two ways to work with a reference: make a copy,
or configure the system to return copies instead of references.
There is a performance penalty to having the system return copies.
Both ways are detailed in [Safe Entry Modification](../../basic_config/data_entries_custom_classes/managing_data_entries.html#managing_data_entries__section_A0E0F889AC344EFA8DF304FD64418809).

## <a id="first-op-with-mixed-types" class="no-quick-link"></a>First Operation with Mixed Region Types

When more than one region participates in a transaction,
and there is at least one partitioned and at least one
replicated region,
the code must do its first operation on the partitioned
region to avoid a `TransactionDataNotColocatedException`.
Write the transaction to do its first operation on a partitioned
region, even if the operation will be spurious.

## <a id="transactions-persistence" class="no-quick-link"></a> Allowing Transactions to Work on Persistent Regions

<%=vars.product_name%>'s implementation of atomic transactions prohibits
regions with persistence from participating in transactions.
The invocation of a persistent region operation within a transaction
throws an `UnsupportedOperationException` with an associated message of

``` pre
Operations on persist-backup regions are not allowed because this thread
has an active transaction
```

An application that wishes to allow operations on a persistent region during
a transaction can set this system property:

`-Dgemfire.ALLOW_PERSISTENT_TRANSACTIONS=true`

Setting this system property eliminates the exception.
It does not change the fact that atomicity is not enforced
for disk writes that occur with the commit of a transaction.
A server crash during the commit may succeed in some,
but not all of the disk writes.

## <a id="transactions-queries" class="no-quick-link"></a>Mixing Transactions with Queries and Indexes

Queries and query results reflect region state, and not any state or
changes that occur within a transaction.
Likewise, the contents and updates to an index do not intersect with any
changes made within a transaction.
Therefore, do not mix transactions with queries or indexed regions.

## <a id="transactions-eviction" class="no-quick-link"></a>Mixing Transactions with Eviction

LRU eviction and transactions work well together.
Any eviction operation on a region entry that is operated on
from within a transaction is deferred until the transaction is committed.
Further, because any entry touched by the transaction
has had its LRU clock reset,
eviction is not likely to choose those entries as victims
immediately after the commit.

## <a id="transactions-expiration" class="no-quick-link"></a>Mixing Transactions with Expiration

A transaction disables expiration on any region entries affected
by the transaction.

## <a id="transactions-dirty-reads" class="no-quick-link"></a>Changing the Handling of Dirty Reads

An application requiring a strict,
but slower isolation model,
such that dirty reads of transitional states are not allowed,
should set a property and encapsulate read operations within the transaction.
Configure this strict isolation model with the property:

```
-Dgemfire.detectReadConflicts=true
```

This property causes read operations to succeed only when they
read a consistent pre- or post-transactional state.
If not consistent,
<%=vars.product_name%> throws a `CommitConflictException`.


